home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 264_01 / wc.c < prev    next >
Text File  |  1980-01-01  |  3KB  |  166 lines

  1. /*
  2.  * wc - word count
  3.  *
  4.  * Usage: wc [-lwc] [file...]
  5.  *
  6.  * Count lines, words, and characters in the named files or stdin.
  7.  * Words are delimited by spaces, tabs, or newlines.  Default action is
  8.  * -lwc. 
  9.  *
  10.  * Flags:
  11.  * -l   display number of lines
  12.  * -w   display number of words
  13.  * -c   display number of characters
  14.  *
  15.  * This program is in the public domain.
  16.  * David MacKenzie
  17.  * 6522 Elgin Lane
  18.  * Bethesda, MD 20817
  19.  *
  20.  * Latest revision: 04/23/88
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25.  
  26. /* Totals in case multiple files are specified. */
  27. long    totnlines = 0L;
  28. long    totnwords = 0L;
  29. long    totnchars = 0L;
  30.  
  31. int     nfiles = 0;        /* Number of files specified. */
  32.  
  33. _main(argc, argv)
  34.     int     argc;
  35.     char  **argv;
  36. {
  37.     void    wc();
  38.     int     lines = 0;        /* Count lines? */
  39.     int     words = 0;        /* Count words? */
  40.     int     chars = 0;        /* Count chars? */
  41.     int     optind;        /* Loop index. */
  42.  
  43.     for (optind = 1; optind < argc && *argv[optind] == '-'; ++optind)
  44.     while (*++argv[optind])
  45.         switch (*argv[optind]) {
  46.         case 'l':
  47.         lines = 1;
  48.         break;
  49.         case 'w':
  50.         words = 1;
  51.         break;
  52.         case 'c':
  53.         chars = 1;
  54.         break;
  55.         default:
  56.         fprintf(stderr, "Usage: wc [-lwc] [file...]\n");
  57.         exit(1);
  58.         }
  59.  
  60.     if (lines + words + chars == 0)
  61.     lines = words = chars = 1;
  62.  
  63.     if (optind == argc) {
  64.     wc("-", lines, words, chars);
  65.     exit(0);
  66.     }
  67.  
  68.     for (; optind < argc; ++optind)
  69.     wc(argv[optind], lines, words, chars);
  70.  
  71.     if (nfiles > 1) {
  72.     if (lines)
  73.         printf("%8ld", totnlines);
  74.     if (words)
  75.         printf("%8ld", totnwords);
  76.     if (chars)
  77.         printf("%8ld", totnchars);
  78.     printf(" total\n");
  79.     }
  80.     exit(0);
  81. }
  82.  
  83. /*
  84.  * Calculate and output the specified counts.
  85.  */
  86.  
  87. void
  88. wc(file, lines, words, chars)
  89.     char   *file;
  90.     char    lines, words, chars;
  91. {
  92.     char   *normalize();
  93.     FILE   *fp;            /* Input file pointer. */
  94.     int     c;            /* One byte of input. */
  95.     long    nlines = 0L;    /* Number of lines in current file. */
  96.     long    nwords = 0L;    /* Ditto for words. */
  97.     long    nchars = 0L;    /* Ditto for characters. */
  98.     char    inword = 0;        /* Were we in a word before this char? */
  99.  
  100.     ++nfiles;
  101.     if (!strcmp(file, "-"))
  102.     fp = stdin;
  103.     else if (!(fp = fopen(file, "r"))) {
  104.     perror(file);
  105.     return;
  106.     }
  107.  
  108.     while ((c = agetc(fp)) != EOF) {
  109.     ++nchars;
  110.     switch (c) {
  111.     case '\n':
  112.         ++nlines;
  113.         /* Fall through. */
  114.     case '\t':
  115.     case ' ':
  116.         if (inword)
  117.         ++nwords;
  118.         inword = 0;
  119.         break;
  120.     default:
  121.         inword = 1;
  122.         break;
  123.     }
  124.     }
  125.  
  126.     if (inword) {
  127.     ++nlines;
  128.     ++nwords;
  129.     }
  130.     totnlines += nlines;
  131.     totnwords += nwords;
  132.     totnchars += nchars;
  133.  
  134.     if (lines)
  135.     printf("%8ld", nlines);
  136.     if (words)
  137.     printf("%8ld", nwords);
  138.     if (chars)
  139.     printf("%8ld", nchars);
  140.     if (fp != stdin)
  141.     printf(" %s", normalize(file));
  142.     printf("\n");
  143.  
  144.     if (fp != stdin)
  145.     (void) fclose(fp);
  146. }
  147.  
  148. /*
  149.  * Convert uppercase letters to lowercase, and non-graphic characters to '?'.
  150.  */
  151.  
  152. char   *
  153. normalize(s)
  154.     char   *s;
  155. {
  156.     char   *t;
  157.  
  158.     for (t = s; *t; ++t)
  159.     if (!isascii(*t) || !isgraph(*t))
  160.         *t = '?';
  161.     else if (isupper(*t) && *t != '_')
  162.         /* Aztec C's ctype thinks that isupper('_') is true . . . */
  163.         *t = tolower(*t);
  164.     return s;
  165. }
  166.